unit cuVector;

interface

uses SysUtils;

type
  {==============================================================}
  {  Coords                                                      }
  {==============================================================}
  TVector2D = class;

  TVector2D = class( TObject )
  public
    X,Y : integer;
    altX,altY : integer;
    constructor Create();
    destructor Destroy(); override;
    procedure setVector2D(nX, nY:integer);
    procedure assignVector2D(Vector2D:TVector2D);
    function ToXY():string; //Returns the Coords in string format, XX:YY, using pretty name (+1)
    function ToX_Y(nSeperator:string):string;
    procedure Rand(Height,Width:integer);
    function getDistance2D(nX,nY:int64):real;
    function getTravel2D(endX,endY:integer;theSpeed:integer):real;
    procedure resizeToResolution2D(theOldWidth,theOldHeight,theNewWidth,theNewHeight:integer);
    procedure moveLeft(theValue:integer = 100);
    procedure moveRight(theValue:integer = 100);
    procedure moveDown(theValue:integer = 100);
    procedure moveUp(theValue:integer = 100);
    procedure fitToScreen(theStartX,theStartY,theBlackSpace:integer;theZoom:real);
    procedure RotateMatrix(const theDegrees:real);
    procedure RotateMatrixUsingTime(const theDegrees, theInitialOrbit:real;const theTime:integer );
  end;

implementation

uses cuDebug, cuMath64;

    {==============================================================}
    {  Coords                                                      }
    {==============================================================}

constructor TVector2D.Create();
begin
  inherited Create();

  X    := -1;
  Y    := -1;
  altX := -1;
  altY := -1;
end;

destructor TVector2D.Destroy();
begin
  inherited Destroy();
end;

function TVector2D.ToXY():string; //Returns the Coords in string format
begin
  result := IntToStr(X+1)+':'+IntToStr(Y+1);
end;

function TVector2D.ToX_Y(nSeperator:string):string; //Returns the Coords in string format
begin
  result := IntToStr(X) + nSeperator + IntToStr(Y);
end;

procedure TVector2D.setVector2D(nX, nY:integer); //Returns the Coords in string format
begin
  X := nX;
  Y := nY;
end;

procedure TVector2D.assignVector2D(Vector2D:TVector2D); //Returns the Coords in string format
begin
  X := Vector2D.X;
  Y := Vector2D.Y;
end;

procedure TVector2D.Rand(Height, Width:integer);
begin
  x := random(height);
  y := random(width);
end;

function TVector2D.getDistance2D(nX,nY:int64):real;
begin
  result := sqrt( sqr(nX-X) + sqr(nY-Y) );
  DevConsole.Print( LOG_DEBUG3, 'Distance from '+ToXY()+' to '+IntToStr(nX)+':'+IntToStr(nY)+' is '+FormatFloat('0.00',result));
end;

function TVector2D.getTravel2D(endX,endY:integer;theSpeed:integer):real;
var theDistance : real;
begin
  theDistance := getDistance2D(endX,endY);

  if (theDistance > 0) then
    result := theDistance / theSpeed
  else
    result := 0;
end;

procedure TVector2D.resizeToResolution2D(theOldWidth,theOldHeight,theNewWidth,theNewHeight:integer);
var percentWidth,percentHeight:real;
begin
  percentWidth := theNewWidth / theOldWidth;
  percentHeight := theNewHeight / theOldHeight;

  X := round(X * percentWidth);
  Y := round(Y * percentHeight);
end;

procedure TVector2D.moveLeft(theValue:integer = 100);
begin
  Dec( X, theValue);
end;
procedure TVector2D.moveRight(theValue:integer = 100);
begin
  Inc( X, theValue);
end;
procedure TVector2D.moveDown(theValue:integer = 100);
begin
  Inc( Y, theValue);
end;
procedure TVector2D.moveUp(theValue:integer = 100);
begin
  Dec( Y, theValue);
end;

procedure TVector2D.fitToScreen(theStartX,theStartY,theBlackSpace:integer;theZoom:real);
{
  1) Adjust XY for StartXY
  2) Adjust XY for Zoom
  3) Adjust XY for blackspace
  4) Adjust startXY for screenCenter
}
var L,T : real; theCenterX,theCenterY:real;
begin
  //Adjust XY for StartXY and Zoom
  L := (X*theZoom) - (theStartX*theZoom);
  T := (Y*theZoom) - (theStartY*theZoom);

  //Adjust XY for BlackSpace
  L := (L / theBlackspace);
  T := (T / theBlackspace);

  // Adjust startXY for screenCenter
  theCenterX := 1280/2;
  theCenterY := 720/2;

  L := L + theCenterX;
  T := T + theCenterY;

  altX := round( L );
  altY := round( T );
end;

procedure TVector2D.RotateMatrix(const theDegrees:real);
var nX,nY : real;  newDegrees : real;
begin
  newDegrees := toRadians( theDegrees );

  nX := round( X*cos(newDegrees) - Y*sin(newDegrees) ); // rotation around the x axis
  nY := round( X*sin(newDegrees) + Y*cos(newDegrees) );

  X := round( nX ); //modifying X or Y above before the trasform is complete will cause a error in end position.
  Y := round( nY );
end;
procedure TVector2D.RotateMatrixUsingTime(const theDegrees, theInitialOrbit:real;const theTime:integer);
var nX,nY : real; newDegrees : real;
begin
  newDegrees := toRadians( theDegrees*theTime ) + toRadians(theInitialOrbit);

  nX := round( X*cos(newDegrees) - Y*sin(newDegrees) ); // rotation around the x axis
  nY := round( X*sin(newDegrees) + Y*cos(newDegrees) );

  X := round( nX ); //modifying X or Y above before the trasform is complete will cause a error in end position.
  Y := round( nY );
end;

end.
